#ifndef __DAF_CONTROL_H__
#define __DAF_CONTROL_H__

#include "daf_model.h"

#include "gazella/async_message.h"

#include <mutex>
#include <functional>
#include <string>
#include <map>
#include <future>

namespace Gazella {
namespace Daf {

struct ControlAsyncMessage: public IAsyncMessage {
    DeviceAgentModel::DeviceAgentProperty cmd;

    std::promise<DeviceAgentModel::DeviceAgentProperty> ack_p;
};

typedef std::function<void(const DeviceAgentModel::DeviceAgentProperty&, DeviceAgentModel::DeviceAgentProperty&)> control_notify_func_t;

class DafControl {
private:
    DafControl();
    ~DafControl();

    void __async_message_notify(const std::shared_ptr<IAsyncMessage>& message);

public:
    static DafControl* get_instance();

    void init();

    void control(const DeviceAgentModel::DeviceAgentProperty& cmd, DeviceAgentModel::DeviceAgentProperty& ack);

    //user's slot func will notify in main thread
    //so the notify func can't be blocked
    bool connect(const std::string& identifier, control_notify_func_t func);

private:
    std::mutex m_notifies_lock; 
    std::map<std::string, control_notify_func_t> m_control_map;

    GzAsyncMessage m_async;
};
} // namespace Daf
} // namespace Gazella


#endif